﻿//功用：数据保存
//创建时间：2020-12-24 14:10:11
//作者：wanghaoli

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using WebNetCorePhoneErp.IDAL;
using WebNetCorePhoneErp.Model;

namespace WebNetCorePhoneErp.IDAL
{
    /// <summary>
    /// 数据操作基接口
    /// </summary>
    public interface IDaoBase<T> where T : class
    {
        int Add(T entity);
        Task<int> AddAsync(T entity);
        int Add(IEnumerable<T> entitys);
        Task<int> AddListAsync(IEnumerable<T> entitys);

        int Update(T entity);
        Task<int> UpdateAsync(T entity);

        /// <summary>
        /// 修改指定的字段
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        Task<int> UpdateAsync(T entity, string[] column);

        /// <summary>
        /// 异步修改集合，修改指定的列
        /// </summary>
        /// <param name="list">集合</param>
        /// <param name="column">指定的列，参考 id,name。要修改的列名传入数组</param>
        /// <returns></returns>
        Task<int> UpdateListAsync(List<T> list, string[] column);

        /// <summary>
        ///  [事务]批量修改或新增或删除(若干个)
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        Task<int> SaveMultipleAsync(List<SaveModel> list);

        int Delete(T entity);

        /// <summary>
        /// 根据主键删除一条
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        Task<int> DeleteByPrimaryKeyAsync(object id);
        Task<int> DeleteAsync(T entity);
        int Delete(Expression<Func<T, bool>> where);
        Task<int> DeleteAsync(Expression<Func<T, bool>> where);

        /// <summary>
        /// 根据主键查询一条
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        T Get(object id);

        /// <summary>
        /// 根据主键异步查询
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        Task<T> GetAsync(object id);

        T Get(Expression<Func<T, bool>> where);

        /// <summary>
        /// 异步查询单条记录
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        Task<T> GetSingleOrDefaultAsync(Expression<Func<T, bool>> where);

        IQueryable<T> GetList(Expression<Func<T, bool>> where);

        /// <summary>
        /// 使用新的数据上下文
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        IQueryable<T> GetListByNewContext(Expression<Func<T, bool>> where);

        /// <summary>
        /// 同步，查询表所有记录
        /// </summary>
        /// <returns></returns>
        List<T> GetListAll();

        List<T> GetListAll(Expression<Func<T, bool>> where);

        /// <summary>
        /// 异步查询集合
        /// </summary>
        /// <param name="where">条件</param>
        /// <returns></returns>
        Task<List<T>> GetListAsync(Expression<Func<T, bool>> where);

        /// <summary>
        /// 异步查询所有记录
        /// </summary>
        /// <returns></returns>
        Task<List<T>> GetAllListAsync();

        IQueryable<T> GetQuery();
        IQueryable<T> GetQuery(Expression<Func<T, bool>> where);
 
        /// <summary>
        /// 检查是否存在
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        bool Any(Expression<Func<T, bool>> where);

        /// <summary>
        /// 检查是否存在
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        Task<bool> AnyAsync(Expression<Func<T, bool>> where);
        int Count(Expression<Func<T, bool>> where);
        Task<int> CountAsync(Expression<Func<T, bool>> where);

        PageModel<G> GetPage<G>(IQueryable<G> query, int pageIndex, int pageSize);
        PageModel<T> GetPage<SortKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> where, Expression<Func<T, SortKey>> orderwhere);

        /// <summary>
        /// 异步，分页查询升序
        /// </summary>
        /// <typeparam name="SortKey"></typeparam>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="where"></param>
        /// <param name="orderByAsc"></param>
        /// <returns></returns>
        /// 2019-10-15 17:17:09 王浩力 添加
        Task<PageModel<T>> GetPageAsync<SortKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> where, Expression<Func<T, SortKey>> orderByAsc);

        /// <summary>
        /// 异步分页，倒序查询
        /// </summary>
        /// <typeparam name="SortKey"></typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">每页记录数</param>
        /// <param name="where">查询条件</param>
        /// <param name="orderByDesc">倒序列</param>
        /// <returns></returns>
        Task<PageModel<T>> GetPageOrderByDescAsync<SortKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> where, Expression<Func<T, SortKey>> orderByDesc);

        /// <summary>
        /// 表联合查询时，可用此方法
        /// </summary>
        /// <typeparam name="G">视图实体类型，装了多个表字段的实体</typeparam>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        Task<PageModel<G>> GetPageAsync<G>(IQueryable<G> query, int pageIndex, int pageSize);

        /// <summary>
        /// 扩展 IQueryable<T>.ToListAsync();，此方法非常实用，可以在bll业务层使用
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        Task<List<G>> ToListAsync<G>(IQueryable<G> query);
    }
}
